# Copyright (C) 2015-2016  Nicola Spanti (RyDroid) <dev@nicola-spanti.info>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.


cmake_minimum_required(VERSION 2.8.9)


set(PROJECT_NAME "PlanetWars2dRT-core")
if (CMAKE_VERSION VERSION_LESS "3.1")
  project("${PROJECT_NAME}")
  # With language parameter as "C", CMake would have forced C90!
else()
  project("${PROJECT_NAME}" C)
endif()


option(BUILD_SHARED_LIB "Build shared library" ON)
option(BUILD_STATIC_LIB "Build static library" ON)
option(BUILD_UNIT_TESTS "Build unit tests"     ON)


# Configuration of compilators

## Compiler flags to add
set(GNU_FLAGS_WARNING  "-Wall -Wextra -Wformat=2 -Wpedantic -Werror")
set(GNU_FLAGS_OPTIMIZE "-O2")
set(GNU_FLAGS_SECURITY "-fPIC -D_FORTIFY_SOURCE=2")
set(GNU_FLAGS_DEBUG    "-O0 -g")
set(GNU_C_FLAGS
  "${GNU_FLAGS_WARNING} ${GNU_FLAGS_OPTIMIZE} ${GNU_FLAGS_SECURITY}")
set(GNU_C_FLAGS_DEBUG
  "${GNU_FLAGS_WARNING} ${GNU_FLAGS_DEBUG}")

## C compiler options
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR
    "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
  set(CMAKE_C_FLAGS       "${CMAKE_C_FLAGS}       ${GNU_C_FLAGS}")
  set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${GNU_C_FLAGS_DEBUG}")
endif()

### C99
if (CMAKE_VERSION VERSION_LESS "3.1")
  if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR
      CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
    set(CMAKE_C_FLAGS       "${CMAKE_C_FLAGS}       -std=c99")
    set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -std=c99")
  endif()
else()
  set(CMAKE_C_STANDARD 99)
endif()


# Version number
set(VERSION_MAJOR "0")
set(VERSION_MINOR "1")
set(VERSION_MICRO "1")

# Configure a header file to pass some of the CMake settings
# to the source code.
configure_file(
  "src/specific/compilation_config.h.in"
  "${PROJECT_BINARY_DIR}/include/PlanetWars2dRT-core/specific/compilation_config.h"
  @ONLY
  )
# Add the binary tree to the search path for include files
# so that we will find compilation_config.h
include_directories(${PROJECT_BINARY_DIR}/include/)


set(LIBRARY_OUTPUT_PATH    lib/)
set(EXECUTABLE_OUTPUT_PATH bin/)
set(LIBRARY_NAME           "planet-wars-2d-rt-core")

include_directories(
  ${PROJECT_SOURCE_DIR}/include/
  ${PROJECT_BINARY_DIR}/include/
  )
file(
  GLOB_RECURSE
  lib_source_files
  src/*
  )
set(exe_source_files src/specific/view/planet-wars-2d-rt-text.c)
list(REMOVE_ITEM lib_source_files ${exe_source_files})

if(BUILD_SHARED_LIB)
  add_library(${LIBRARY_NAME} SHARED ${lib_source_files})
  install(TARGETS ${LIBRARY_NAME} DESTINATION lib)
  add_executable(planet-wars-2d-rt-text ${exe_source_files})
  target_link_libraries(
    planet-wars-2d-rt-text
    ${LIBRARY_NAME} m
    )
endif()

if(BUILD_STATIC_LIB)
  add_library(${LIBRARY_NAME}_static STATIC ${lib_source_files})
  add_executable(planet-wars-2d-rt-text_static ${exe_source_files})
  target_link_libraries(
    planet-wars-2d-rt-text_static
    ${LIBRARY_NAME}_static m
    )
endif()


if(BUILD_UNIT_TESTS)
  enable_testing()
  include(FindPkgConfig)
  pkg_search_module(CHECK OPTIONAL check)
  if(CHECK_FOUND)
    message("Using shared check")
    if(UNIX)
      set(CHECK_LIBRARIES ${CHECK_LIBRARIES} pthread)
    endif()
  else()
    message("Using static check")
    include_directories(
      externals/check/build/src/
      externals/check/build/
      )
    link_directories(
      ${CMAKE_SOURCE_DIR}/externals/check/build/src/
      ${CMAKE_SOURCE_DIR}/externals/check/build/lib/
      )
    set(CHECK_LIBRARIES
      libcheck.a libcompat.a
      rt # timer_*
      m  # math
      )
  endif()
  
  include_directories(${PROJECT_SOURCE_DIR}/tests/)
  
  add_executable(check_bool tests/check_bool.c)
  target_link_libraries(check_bool ${CHECK_LIBRARIES})
  add_test(
    check_bool
    "${EXECUTABLE_OUTPUT_PATH}/check_bool"
    )
  
  add_executable(check_vector_generic tests/check_vector_generic.c)
  target_link_libraries(check_vector_generic ${CHECK_LIBRARIES})
  add_test(
    check_vector_generic
    "${EXECUTABLE_OUTPUT_PATH}/check_vector_generic"
    )
  
  add_executable(check_color_rgb tests/check_color_rgb.c)
  target_link_libraries(check_color_rgb ${CHECK_LIBRARIES})
  add_test(
    check_color_rgb
    "${EXECUTABLE_OUTPUT_PATH}/check_color_rgb"
    )
  
  add_executable(check_statistics tests/check_statistics.c)
  target_link_libraries(check_statistics ${CHECK_LIBRARIES})
  add_test(
    check_statistics
    "${EXECUTABLE_OUTPUT_PATH}/check_statistics"
    )
  
  add_executable(
    check_cstring_functions
    tests/check_cstring_functions.c
    )
  target_link_libraries(
    check_cstring_functions
    ${LIBRARY_NAME} ${CHECK_LIBRARIES})
  add_test(
    check_cstring_functions
    "${EXECUTABLE_OUTPUT_PATH}/check_cstring_functions"
    )
  
  add_executable(
    check_arguments_management
    tests/check_arguments_management.c
    )
  target_link_libraries(
    check_arguments_management
    ${LIBRARY_NAME} ${CHECK_LIBRARIES})
  add_test(
    check_arguments_management
    "${EXECUTABLE_OUTPUT_PATH}/check_arguments_management"
    )
  
  add_executable(
    check_ship
    tests/check_ship.c
    )
  target_link_libraries(
    check_ship
    ${LIBRARY_NAME} ${CHECK_LIBRARIES}
    )
  add_test(
    check_ship
    "${EXECUTABLE_OUTPUT_PATH}/check_ship"
    )
  
  add_executable(
    check_ship_observers
    tests/check_ship_observers.c
    )
  target_link_libraries(
    check_ship_observers
    ${LIBRARY_NAME} ${CHECK_LIBRARIES}
    )
  add_test(
    check_ship_observers
    "${EXECUTABLE_OUTPUT_PATH}/check_ship_observers"
    )
  
  add_executable(
    check_planet
    tests/check_planet.c
    )
  target_link_libraries(
    check_planet
    ${LIBRARY_NAME} ${CHECK_LIBRARIES}
    )
  add_test(
    check_planet
    "${EXECUTABLE_OUTPUT_PATH}/check_planet"
    )
  
  add_executable(
    check_planet_observers
    tests/check_planet_observers.c
    )
  target_link_libraries(
    check_planet_observers
    ${LIBRARY_NAME} ${CHECK_LIBRARIES}
    )
  add_test(
    check_planet_observers
    "${EXECUTABLE_OUTPUT_PATH}/check_planet_observers"
    )
  
  add_executable(
    check_universe
    tests/check_universe.c
    )
  target_link_libraries(
    check_universe
    ${LIBRARY_NAME} ${CHECK_LIBRARIES}
    )
  add_test(
    check_universe
    "${EXECUTABLE_OUTPUT_PATH}/check_universe"
    )
  
  add_executable(
    check_universe_observers
    tests/check_universe_observers.c
    )
  target_link_libraries(
    check_universe_observers
    ${LIBRARY_NAME} ${CHECK_LIBRARIES}
    )
  add_test(
    check_universe_observers
    "${EXECUTABLE_OUTPUT_PATH}/check_universe_observers"
    )
  
  add_executable(
    check_universes_hard_coded
    tests/check_universes_hard_coded.c
    )
  target_link_libraries(
    check_universes_hard_coded
    ${LIBRARY_NAME} ${CHECK_LIBRARIES}
    )
  add_test(
    check_universes_hard_coded
    "${EXECUTABLE_OUTPUT_PATH}/check_universes_hard_coded"
    )
  
  add_executable(
    check_game_players
    tests/check_game_players.c
    )
  target_link_libraries(
    check_game_players
    ${LIBRARY_NAME} ${CHECK_LIBRARIES}
    )
  add_test(
    check_game_players
    "${EXECUTABLE_OUTPUT_PATH}/check_game_players"
    )
  
  add_executable(
    check_game_observers
    tests/check_game_observers.c
    )
  target_link_libraries(
    check_game_observers
    ${LIBRARY_NAME} ${CHECK_LIBRARIES}
    )
  add_test(
    check_game_observers
    "${EXECUTABLE_OUTPUT_PATH}/check_game_observers"
    )
  
  add_executable(
    check_game_end
    tests/check_game_end.c
    )
  target_link_libraries(
    check_game_end
    ${LIBRARY_NAME} ${CHECK_LIBRARIES}
    )
  add_test(
    check_game_end
    "${EXECUTABLE_OUTPUT_PATH}/check_game_end"
    )
  
  add_executable(
    check_player_robots
    tests/check_player_robots.c
    )
  target_link_libraries(
    check_player_robots
    ${LIBRARY_NAME} ${CHECK_LIBRARIES}
    )
  add_test(
    check_player_robots
    "${EXECUTABLE_OUTPUT_PATH}/check_player_robots"
    )
  
  add_executable(
    check_game_state_basic
    tests/check_game_state_basic.c
    )
  target_link_libraries(
    check_game_state_basic
    ${LIBRARY_NAME} ${CHECK_LIBRARIES}
    )
  add_test(
    check_game_state_basic
    "${EXECUTABLE_OUTPUT_PATH}/check_game_state_basic"
    )
  
  add_executable(
    check_game_state
    tests/check_game_state.c
    )
  target_link_libraries(
    check_game_state
    ${LIBRARY_NAME} ${CHECK_LIBRARIES}
    )
  add_test(
    check_game_state
    "${EXECUTABLE_OUTPUT_PATH}/check_game_state"
    )
endif()


# Package


set(DESCRIPTION_SUMMARY
  "A free/libre real-time 2D planet wars game libray")
set(DESCRIPTION
  "It is a free/libre real-time 2D planet wars game libray. It provide the model, the controller and some useful components for a view. It is in C.")
set(URL "https://gitlab.com/RyDroid/PlanetWars2dRT-core")
set(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_MICRO}")
set(EMAIL "dev@nicola-spanti.info")
set(VCS_WWW "https://gitlab.com/RyDroid/PlanetWars2dRT-core")
set(VCS_GIT "https://gitlab.com/RyDroid/PlanetWars2dRT-core.git")


## pkg-config
# https://www.freedesktop.org/wiki/Software/pkg-config/
configure_file(
  "planet-wars-2d-rt-core.pc.in"
  "${PROJECT_BINARY_DIR}/planet-wars-2d-rt-core.pc"
  @ONLY
  )


set(CPACK_GENERATOR "TBZ2;TGZ;STGZ;TZ;ZIP")
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
  set(CPACK_GENERATOR "${CPACK_GENERATOR};DEB;RPM")
endif()

set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${VERSION_MICRO})

set(CPACK_PACKAGE_NAME                "lib${LIBRARY_NAME}")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${DESCRIPTION_SUMMARY}")
set(CPACK_PACKAGE_DESCRIPTION         "${DESCRIPTION}")
set(CPACK_PACKAGE_VENDOR              "Nicola Spanti")
set(CPACK_PACKAGE_CONTACT             "${EMAIL}")
set(CPACK_RESOURCE_FILE_LICENSE       "${CMAKE_SOURCE_DIR}/LICENSE.md")
set(CPACK_RESOURCE_FILE_README        "${CMAKE_SOURCE_DIR}/README.md")

set(CPACK_DEBIAN_PACKAGE_NAME         "${CPACK_PACKAGE_NAME}")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER   "${CPACK_PACKAGE_VENDOR} <${CPACK_PACKAGE_CONTACT}>")
set(CPACK_DEBIAN_PACKAGE_SUMMARY      "${DESCRIPTION_SUMMARY}")
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION  "${DESCRIPTION}")
set(CPACK_DEBIAN_PACKAGE_VERSION      "${CPACK_PACKAGE_VERSION}")
set(CPACK_DEBIAN_PACKAGE_DEPENDS      "libc6")
set(CPACK_DEBIAN_PACKAGE_SECTION      "libs")
set(CPACK_DEBIAN_PACKAGE_PRIORITY     "optional")
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE     "${URL}")
set(CPACK_DEBIAN_PACKAGE_URL          "${URL}")
set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE)

set(CPACK_RPM_PACKAGE_NAME            "${CPACK_PACKAGE_NAME}")
set(CPACK_RPM_PACKAGE_SUMMARY         "${DESCRIPTION_SUMMARY}")
set(CPACK_RPM_PACKAGE_DESCRIPTION     "${DESCRIPTION}")
set(CPACK_RPM_PACKAGE_VERSION         "${CPACK_PACKAGE_VERSION}")
set(CPACK_RPM_PACKAGE_VENDOR          "${CPACK_PACKAGE_VENDOR}")
set(CPACK_RPM_PACKAGE_HOMEPAGE        "${URL}")
set(CPACK_RPM_PACKAGE_URL             "${URL}")

include(CPack)
